/**
* @file decompose.h
* March, 2014
* 
* @brief class to decompose quad-mesh in mapping mesh.
* 
* @author Antonio Miranda (amiranda@tecgraf.puc-rio.br )
* 
* @see 
*/

// includes
//----------

#ifndef _DECOMPOSE_QUAD_MESH_H_
#define _DECOMPOSE_QUAD_MESH_H_

#include <vector>
#include <string>
#include "topology.hpp"


using namespace std;

//
//////////////////////////////////////////////////////////////////////////
class decomposeQuadMesh
{
public:
  decomposeQuadMesh(cTopology *top);
  ~decomposeQuadMesh(void);

  bool process ();

  // get decomposed quad-mesh
  void       getDMesh (int *np, double **pts, int *ne, int **conn);
  cTopology *getDMesh ( );


private:

  // current boundary mesh
  cTopology *m_topol;

  // quadrilateral elements that represent a mapping mesh
  vector <int>     m_quad_conn;
  vector <double>  m_quad_pts;


  // get internal points from a initial one. This function walk through edges
  // with info = 0 and mark them with info = 1. Return the point in a vector
  // with n+1 position.
  void getInternalIdPoints (int init_pts, int init_edge, vector <int> &points);

  //          +---------------+---------------+
  //          |               |               |
  //          |               |               |
  //          |               |               | 
  //          |               |               |
  //          |               |               |
  //          | curr_edge     |  next_edge    |
  //   v_base +---------------+---------------+
  //          |               |               |
  //          |               |               |
  //          |               |               | 
  //          |               |               |
  //          |               |               |
  //          |               |               |
  //          +---------------+---------------+
  //
  // Get next (opposite) edge based on base vertex v_base and curr_edge
  int  nextOppositeEdge (int curr_edge, int v_base);


  // receive a dividing curve, that can intersected with other, and split it if necessary, because 
  void splitCurve (vector <int> &temp_curve, vector < vector<int> > &div_curve);

  // get points and quadrilateral elements
  void getDividingPoints (vector < vector<int> > &div_curve);
  void getQuadConnect    (vector < vector<int> > &div_curve);

  // given id i and j of a edge (on a dividing curve), return next 
  // id i and j of next edge that loop a new quad element.
  void nextEdgeOnQuad (int edge_i, int edge_j, int nxt_edge_i, int nxt_edge_j);

  // given an edge with i and j ids, return the adjacent element that have
  // this edge with same sequence i -> j.
  int adjElemToEdgeIJ (int edge_i, int edge_j);

  // given an element and id node, return the previous of this node.
  int prevNodeElem (int elem, int id_node);






  void writeDecompToVTK (string filename, vector < vector<int> > ids_pts);

  void writeMeshToVTK  (string filename);

};


#endif